# -*-coding:Utf-8 -*
""" Gameplay Package
"""
import types, functools
from ..common import *

def nothing(item,*args, **kwargs):
	return

def default_loading(self,head,body):
	if 'attr' in head:
		if type(head['attr']) == list:
			for tag in head['attr']:
				for aK in tag[0]:
					setattr(self,aK,tag[0][aK])
		elif type(head['attr']) == tuple:
				for aK in tag[0]:
					setattr(self,aK,tag[0][aK])
	self.ItName = head['name']

class MetaItem(type):
	
	ItemClass = {}
	ItemFunction = {'Nothing':nothing}
	ItemData = []
	ItemInstance = {}
	
	def __new__(metacls, name, bases, dico):
		init_dico = {}
		for k in dico:
			if k[0] != '_' and callable(dico[k]) and k != 'Nothing':
				metacls.ItemFunction[k] = dico[k]
			else:
				init_dico[k] = dico[k]
		newAbilities = {}
		init_dico['_abilities_'] = []
		for aB in bases:
			if hasattr(aB,'_abilities_'):
				init_dico['_abilities_'] += list(aB._abilities_)
		if '_abilities_' in dico and type(dico['_abilities_']) == dict:
			for k in dico['_abilities_']:
				func = nothing
				if dico['_abilities_'][k] in metacls.ItemFunction:
					func = metacls.ItemFunction[dico['_abilities_'][k]]
				newAbilities[k] = func
			init_dico['_abilities_'] = tuple(list(dico['_abilities_'].keys())+init_dico['_abilities_'])
		init_dico.update(newAbilities)
		if name in metacls.ItemClass:
			metacls.ItemClass[name]._abilities_ = list(metacls.ItemClass[name]._abilities_)
			for k in newAbilities:
				if not k in metacls.ItemClass[name]._abilities_:
					metacls.ItemClass[name]._abilities_.append(k)
				setattr(metacls.ItemClass[name],k,newAbilities[k])
			metacls.ItemClass[name]._abilities_ = tuple(metacls.ItemClass[name]._abilities_)
		else:
			metacls.ItemClass[name] = type.__new__(metacls, name, bases, init_dico)
			if not hasattr(metacls.ItemClass[name],'_loading_'):
				metacls.ItemClass[name]._loading_ = default_loading
		return metacls.ItemClass[name]
		
	def _parseItem_(cls,item):
		if item.h['id'] in MetaItem.ItemInstance:
			return MetaItem.ItemInstance[item.h['id']]
		newItem = cls()
		for k in item.b:
			if type(item.b[k]) == tuple and k in cls._abilities_:
				funcName = item.b[k][0] if type(item.b[k][0]) == str else item.b[k][0][0]
				if funcName not in MetaItem.ItemFunction:
					continue
				func = MetaItem.ItemFunction[funcName]
				if item.b[k][1] != {}:
					func = functools.partial(func,**item.b[k][1])
				setattr(newItem,k,types.MethodType(func,newItem))
		newItem._loading_(item.h,item.b)
		MetaItem.ItemInstance[item.h['id']] = newItem
		return newItem

class Item(object, metaclass = MetaItem):
	
	_abilities_ = {
		'pickup':'Nothing'
	}
	
	def __init__(self):
		self.ItType = 0
		self.ItName = "The Useless Item"
		
class UsableItem(Item):
	
	_abilities_ = {
		'first':'Nothing',
		'second':'Nothing',
		'third':'Nothing',
		'picked':'Nothing',
		'taken':'Nothing'
	}
		
	
